# Figure_A15.R

# Part of the replication archive for 
#
#   Bullock, John G. 2020. "Education and Attitudes toward Redistribution in
#   the United States." British Journal of Political Science 50.


# This file produces Figure A15 in the appendix to the article: "U.S. High
# School Graduation Rates, 1900-2010." 


library(car)       # for Recode()
library(dplyr)
library(grid)
library(lattice)
library(readxl)    # for read_excel()
library(reshape2)  # for melt()



########################################
# PRELIMINARIES FOR PRINTING THE FIGURE
########################################
dirOutput       <- 'float_output/'
filenameStem    <- 'Figure_A15'
PDFtitle        <- 'Figure A15: National graduation rates over time'
PS_width        <- 9.5
PS_height       <- 12.0
postscriptBackground   <- 'transparent'
panelwidth      <- list(5.50, "inches")
panelheight     <- list(3.20, "inches")  
plotLineColor   <- 'black'
plotLineWidth   <- 1
panelBorderCol  <- 'black'
panelNumberCol  <- grey(.2)                    # color of number of each panel; lower values are darker
panelborderwidth <- .3
panelLayout     <- c(1, 1)                     # columns, then rows
xBetween        <- 1.8000                      # space between columns
yBetween        <- 1.3175                      # space between rows
panel.xlim      <- c(1900, 2010)                        
panel.ylim      <- c(0, 80)  
stripTextSize   <-  .75                        # cex
xaxtextsize     <-  .8*.87                     # cex
yaxtextsize     <-  .8*.87                     # cex
yaxtext         <- paste(seq(10, 70, by = 10), '%', sep='')
axisTickSize    <- .4
xAxis            <- list(draw=TRUE, 
                        labels = seq(1900, 2010, by = 10), 
                        at     = seq(1900, 2010, by = 10),
                        tck    = c(axisTickSize, 0), 
                        col    = panelBorderCol, 
                        cex    = xaxtextsize,
                        alternating=1, 
                        relation='free', 
                        axs='i')               # axs='i' means that there is no padding around the xlimits
yAxis            <- list(draw   = TRUE,
                        labels = yaxtext, 
                        at     = seq(10, 70, by = 10),
                        tck    = c(axisTickSize, 0),
                        col    = panelBorderCol,
                        cex    = yaxtextsize,
                        alternating=1,
                        relation='free',       # but the ylim will constrain all panels to same height
                        rot=90,
                        axs='i')

                    

###########################################
# CREATE THE DATA FRAME
###########################################
# Download the data: Table 110 of the 2010 Digest of Education Statistics.
# AFGR = "averaged freshman graduation rate": what proportion of freshman in 
#        public schools graduate after four years?
# pop17 = graduates as a ratio of the 17-year-old population
gradRatesOriginal <- tempfile(fileext = '.xls')
download.file(
  url      = 'https://nces.ed.gov/programs/digest/d10/tables/xls/tabn110.xls', 
  destfile = gradRatesOriginal, mode = "wb")
gradRatesDF <- read_excel(gradRatesOriginal) %>%
  slice(6:66) %>%
  select(1, 10, 12) %>%
  na.omit(.) %>%
  rename(year = 1, AFGR = 2, pop17 = 3) %>%
  mutate(AFGR = na_if(AFGR, "---")) %>%
    mutate(AFGR = na_if(AFGR, "      ---")) %>%
    mutate(AFGR = as.numeric(AFGR)) %>%
  mutate(pop17 = as.numeric(pop17)) %>%
  mutate(year = gsub('(\\d{2})\\d{2}-(\\d{2}).*', '\\1\\2', year)) %>%
    mutate(year = Recode(.$year, '1819=1900') ) 
gradRatesDF$year[41] <- 2000
gradRatesDF <- melt(gradRatesDF, id.vars = 'year', variable.name = 'type', value.name = 'percentage')





########################################
# PANEL FUNCTION
########################################
sparkline.panel <- function(...) { 
  trellis.par.set("clip", list(panel="on", strip="on")) # for permitting panel.axis(outside=T, ...)
  panel.xyplot(...)
  
  # Y AXIS
  grid.text('years required', x=-.23, y=.48, gp=gpar(font=1, cex=.705, col=panelBorderCol), rot=90)    

  # TICK MARKS AT TOP AND RIGHT-HAND SIDE OF PANEL
  panel.axis(
    side        = "top",
    at          = xAxis$at,
    draw.labels = FALSE,
    half        = FALSE,
    tck         = axisTickSize)
  panel.axis(
    side        = "right",
    at          = yAxis$at,
    draw.labels = FALSE,
    half        = FALSE,
    tck         = axisTickSize)
}



########################################
# PRINT THE PDF FILE
########################################
pdf(
  file   = paste0(dirOutput, filenameStem, '.pdf'), 
  width  = PS_width, 
  height = PS_height, 
  paper  = "special", 
  title  = PDFtitle,
  bg     = postscriptBackground)
trellis.par.set(
  "axis.line", 
  list(alpha=1, col=panelBorderCol, lty=1, lwd=panelborderwidth))  
trellis.par.set(
  superpose.line = list(
    alpha=c(1,1), 
    col=c('black', plotLineColor), 
    lty=c("43", "solid"), 
    lwd=c(1, plotLineWidth)))
tmp <- trellis.par.get('axis.components')
tmp$left$pad1 <- 0.5  # distance between axis ticks and tick labels
trellis.par.set('axis.components', tmp)
gradRatesPlot <- xyplot(
  percentage ~ year,
  groups   = type,
  data     = gradRatesDF, 
  type     = 'l',
  panel    = sparkline.panel,
  xlim     = panel.xlim,
  ylim     = panel.ylim,
  strip    = FALSE,
  scales   = list(x=xAxis, y=yAxis),
  xlab     = '',
  ylab     = '',
  par.settings = trellis.par.set("clip", list(panel="on", strip="on"))
)
print(gradRatesPlot, panel.width=panelwidth, panel.height=panelheight)
dev.off()


# CROP THE PDF AND CLEAN UP INTERMEDIATE FILES
if (!(Sys.which('pdfcrop')=='' | Sys.which('perl')=='')  |  'pdfcrop' %in% installed.packages()[, 'Package']) {  # if "pdfcrop" is installed 
  system(paste(
    if (Sys.info()['sysname']=='Windows') paste(Sys.getenv('Comspec'), '/c ') else '',
    'pdfcrop', 
    paste0(dirOutput, filenameStem, '.pdf'), 
    paste0(dirOutput, filenameStem, '_crop.pdf')))
  file.remove(paste0(dirOutput, filenameStem, '.pdf'))
  if (interactive() & Sys.info()['sysname']=='Windows') shell.exec(paste0(normalizePath(dirOutput), filenameStem, '_crop.pdf'))
}